import copy
import typing
import logging

from load_planner.models import Task


class PrinterLogger:
    __logger__ = print
    debug = lambda *args, **kwargs: print(*args, **kwargs)
    info = lambda *args, **kwargs: print(*args, **kwargs)
    warn = lambda *args, **kwargs: print(*args, **kwargs)
    error = lambda *args, **kwargs: print(*args, **kwargs)


class ContextualLogger:
    def __init__(self, base_logger: logging.Logger, context: dict):
        self.debug = self.__do_patch(base_logger.debug)
        self.info = self.__do_patch(base_logger.info)
        self.warn = self.__do_patch(base_logger.warn)
        self.error = self.__do_patch(base_logger.error)
        self._context = context

    def __do_patch(self, base_log_method: typing.Callable):
        def patched_method(msg, **extra_context):
            extra = copy.deepcopy(self._context)
            extra.update(extra_context)
            base_log_method(msg, extra=extra)

        return patched_method


def get_task_logger(task: Task) -> ContextualLogger:
    task_logger = logging.getLogger('task')

    creator = task.creator
    tenant = creator.tenant

    context = {
        'user': {
            'id': creator.id,
            'email': creator.email,
            'username': creator.username,
        },
        'tenant': {
            'id': tenant.id,
            'organization': tenant.organization,
            'schema_name': tenant.schema_name,
        },
        'task': {
            'id': task.id,
            'name': task.name
        },
    }
    return ContextualLogger(task_logger, context=context)
